﻿using Furion.DataEncryption;
using Furion.FriendlyException;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Http;
using ZeroAdmin.Application.Entity;
using ZeroAdmin.Core;

namespace ZeroAdmin.Application;

/// <summary>
/// 认证服务
/// </summary>
/// <param name="httpContextAccessor"></param>
public class AuthService(IHttpContextAccessor httpContextAccessor) : IAuthService
{
    private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor;

    /// <summary>
    /// 登入
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<LoginOutput> Login(LoginInput input)
    {
        var encryptPassword = MD5Encryption.Encrypt(input.Password);

        var user = await SqlSugarHelper.Queryable<User>().FirstAsync(x => x.PhoneNumber.Equals(input.PhoneNumber));

        if (user == null)
        {
            throw Oops.Bah("用户不存在。");
        }
        else if (!user.Password.Equals(encryptPassword))
        {
            throw Oops.Bah("账号密码错误。");
        }

        return await CreateToken(user);
    }

    /// <summary>
    /// 创建Token
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    private async Task<LoginOutput> CreateToken(User input)
    {
        string AccessToken = JWTEncryption.Encrypt(new Dictionary<string, object>()
        {
            {ClaimConst.UserId, input.Id },
            {ClaimConst.PhoneNumber, input.PhoneNumber },
            {ClaimConst.OwnerUserId, input.OwnerUserId }
        }, 1440);

        // 设置Swagger自动登入
        _httpContextAccessor.HttpContext.SigninToSwagger(AccessToken);
        // 生成刷新Token
        string RefreshToken = JWTEncryption.GenerateRefreshToken(AccessToken, 2880);
        // 设置刷新Token令牌
        _httpContextAccessor.HttpContext.Response.Headers["access-token"] = AccessToken;
        _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = RefreshToken;

        UnifyContext.Fill(new { AccessToken, RefreshToken });

        // 更新用户信息
        input.LastLoginTime = DateTime.Now;
        await SqlSugarHelper.UpdateAsync(input);

        LoginOutput loginOutput = new LoginOutput();
        loginOutput.UserId = input.Id;
        loginOutput.PhoneNumber = input.PhoneNumber;
        loginOutput.UserName = input.UserName;
        if (input.RoleId != 0)
        {
            Role role = await SqlSugarHelper.Queryable<Role>().FirstAsync(x => x.Id == input.RoleId);
            if (role != null)
            {
                loginOutput.RoleId = role.Id;
                loginOutput.RoleName = role.RoleName;
                loginOutput.RolePermission = role.RolePermission;
            }
        }
        return loginOutput;
    }

    /// <summary>
    /// 登出
    /// </summary>
    public void Logout()
    {
        _httpContextAccessor.HttpContext.SignoutToSwagger();
    }
}
